package com.boyou.sytzc.utils.camera;

import android.content.Context;
import android.graphics.PixelFormat;
import android.hardware.Camera;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.widget.FrameLayout;
import android.widget.Toast;

import com.yuge.yugecse.util.device.DeviceUtil;

import java.io.IOException;
import java.util.Iterator;
import java.util.List;

/**
 * Created by cosecant on 15-9-15.
 * 相机辅助工具
 */
public class CameraUtil {

    public interface OnCameraListener {
        /**
         * 预览状态改变事件
         **/
        void onPreviewStateChanged(boolean isPreview);

        /**
         * 是否支持缩放事件
         **/
        void onSupportZoom(boolean isSupport, int value, int max);
    }

    public static final String TAG = CameraUtil.class.getSimpleName();
    private Context context;
    private Camera camera;//相机设备
    private int scr_width, scr_height;
    private boolean isPreview = false;//是否支持预览
    private boolean isSupportZoom = false;//是否支持相机缩放
    private boolean isSupportAutoFocus = false;//是否支持自动聚焦
    private FrameLayout rootView;//根视图
    private SurfaceView surfaceView;//显示视图的View
    private OnCameraListener listener;
    private boolean isCanTakePicture = false;

    public CameraUtil(Context context, FrameLayout rootView) {
        this.context = context;
        this.rootView = rootView;
        scr_width = DeviceUtil.getScreenWidth(this.context);
        scr_height = DeviceUtil.getScreenHeight(this.context);
    }

    public void setOnCameraListener(OnCameraListener listener) {
        this.listener = listener;
    }

    private final class SurfaceViewCallback implements SurfaceHolder.Callback {
        /**
         * surfaceView 被创建成功后调用此方法
         */
        @Override
        public void surfaceCreated(final SurfaceHolder holder) {
            Log.d(TAG, "surfaceCreated");
            try {
                /*
                 * 在SurfaceView创建好之后 打开摄像头
                 * 注意是 android.hardware.Camera
                 */
                camera = Camera.open(getDefaultCameraId());
                /*
                 * This method must be called before startPreview(). otherwise surfaceview没有图像
                 */
                camera.setPreviewDisplay(holder);
                try {
                    camera.autoFocus(autoFocusCallback);
                    isSupportAutoFocus = true;
                } catch (Exception e) {
                    e.printStackTrace();
                    isSupportAutoFocus = false;
                }
                Camera.Parameters parameters = camera.getParameters();
                if (listener != null) {
                    isSupportZoom = parameters.isSmoothZoomSupported();
                    listener.onSupportZoom(isSupportZoom, parameters.getZoom(), parameters.getMaxZoom());
                }
                /* 设置预览照片的大小，此处设置为全屏 */ // 选择合适的预览尺寸
                List<Camera.Size> sizeList = parameters.getSupportedPreviewSizes();
                // 如果sizeList只有一个我们也没有必要做什么了，因为就他一个别无选择
                if (sizeList.size() > 1) {
                    Iterator<Camera.Size> itor = sizeList.iterator();
                    while (itor.hasNext()) {
                        Camera.Size cur = itor.next();
                        if (cur.width >= scr_width
                                && cur.height >= scr_height) {
                            scr_width = cur.width;
                            scr_height = cur.height;
                            break;
                        }
                    }
                }
                parameters.setPreviewSize(scr_width, scr_height);
                /* 每秒从摄像头捕获5帧画面， */
                parameters.setPreviewFrameRate(3);
                /* 设置照片的输出格式:jpg */
                parameters.setPictureFormat(PixelFormat.JPEG);
                /* 照片质量 */
                parameters.set("jpeg-quality", 85);
                /* 设置照片的大小：此处照片大小等于屏幕大小 */
//          parameters.setPictureSize(display.getWidth(), display.getHeight());
                parameters.setPictureSize(scr_width, scr_height);
                /* 将参数对象赋予到 camera 对象上 */
                try {
                    camera.setParameters(parameters);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                camera.startPreview();
                /**
                 * Installs a callback to be invoked for every preview frame in addition to displaying them on the screen.
                 * The callback will be repeatedly called for as long as preview is active. This method can be called at
                 * any time, even while preview is live. Any other preview callbacks are overridden.
                 * a callback object that receives a copy of each preview frame, or null to stop receiving
                 */
//                camera.setPreviewCallback(new Camera.PreviewCallback() {
//
//                    @Override
//                    public void onPreviewFrame(byte[] data, Camera camera) {
//                        //在视频聊天中，这里传送本地frame数据给remote端
//                        Log.d(TAG, "camera:" + camera);
//                        Log.d(TAG, "byte:" + data);
//                    }
//
//                });
                isCanTakePicture = true;
                isPreview = true;
            } catch (IOException e) {
                e.printStackTrace();
            }

        }

        @Override
        public void surfaceChanged(SurfaceHolder holder, int format, int width,
                                   int height) {
            Log.d(TAG, "surfaceChanged");
        }

        /**
         * SurfaceView 被销毁时释放掉 摄像头
         */
        @Override
        public void surfaceDestroyed(SurfaceHolder holder) {
            releaseCamera();//销毁相机
        }
    }

    /**
     * 自动聚焦回调
     **/
    Camera.AutoFocusCallback autoFocusCallback = new Camera.AutoFocusCallback() {
        @Override
        public void onAutoFocus(boolean success, Camera camera) {
        }
    };

    /**
     * 初始化相机
     **/
    public void initCamera(SurfaceView surfaceView) {
        if (this.surfaceView == null) {
            this.surfaceView = surfaceView;
            this.surfaceView.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
            this.surfaceView.getHolder().setFixedSize(scr_width, scr_height);
            this.surfaceView.getHolder().setKeepScreenOn(true);
            this.surfaceView.getHolder().addCallback(new SurfaceViewCallback());
            isPreview = true;//默认为开启了预览的
            isCanTakePicture = true;
        }
    }

    /**
     * 恢复预览
     **/
    public void resumePreview() {
        if (camera != null && !isPreview) {
            try {
                camera.autoFocus(autoFocusCallback);
            } catch (Exception err) {
                err.printStackTrace();
            }
            camera.startPreview();
            isPreview = true;
            isCanTakePicture = true;
            if (listener != null)
                listener.onPreviewStateChanged(isPreview);
        }
    }

    /**
     * 停止预览
     **/
    public void stopPreview() {
        if (camera != null && isPreview) {
            isPreview = false;
            isCanTakePicture = false;
            camera.stopPreview();
            if (listener != null)
                listener.onPreviewStateChanged(isPreview);
        }
    }

    /**
     * 拍照操作
     **/
    public void takePhoto(final Camera.PictureCallback callback) {
        if (camera != null && isPreview) {
            camera.takePicture(new Camera.ShutterCallback() {
                @Override
                public void onShutter() {
                }
            }, null, new Camera.PictureCallback() {
                @Override
                public void onPictureTaken(byte[] data, Camera camera) {
                    isPreview = false;
                    isCanTakePicture = true;
                    callback.onPictureTaken(data, camera);
                }
            });
        }
    }

    /**
     * 设置相机缩放
     **/
    public void setCameraZoom(int value) {
        try {
            if (isSupportZoom && value >= 0 && value <= 100)
                camera.startSmoothZoom(value);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 释放相机资源
     **/
    public void releaseCamera() {
        try {
            if (camera != null) {
                /* 若摄像头正在工作，先停止它 */
                if (isPreview) {
                    camera.stopPreview();
                    isPreview = false;
                    if (listener != null)
                        listener.onPreviewStateChanged(isPreview);
                }
                //如果注册了此回调，在release之前调用，否则release之后还回调，crash
                camera.setPreviewCallback(null);
                camera.release();
                camera = null;
            }
//            if(surfaceView!=null) {
//                rootView.removeView(surfaceView);//移除surfaceview
//                surfaceView = null;
//            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 自动聚焦
     **/
    public void autoFocus() {
        if (camera != null && isPreview && isSupportAutoFocus) {
            camera.autoFocus(autoFocusCallback);
        }
    }

    /**
     * 获取默认的相机ID
     **/
    private int getDefaultCameraId() {
        int defaultId = -1;

        // Find the total number of cameras available
        int mNumberOfCameras = Camera.getNumberOfCameras();

        // Find the ID of the default camera
        Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
        for (int i = 0; i < mNumberOfCameras; i++) {
            Camera.getCameraInfo(i, cameraInfo);
            if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {
                defaultId = i;
            }
        }
        if (-1 == defaultId) {
            if (mNumberOfCameras > 0) {
                // 如果没有后向摄像头
                defaultId = 0;
            } else {
                // 没有摄像头
                Toast.makeText(context, "手机不支持拍照!", Toast.LENGTH_LONG).show();
            }
        }
        return defaultId;
    }

    public Camera getCamera() {
        return camera;
    }

    public boolean isPreview() {
        return isPreview;
    }

    public boolean isSupportZoom() {
        return isSupportZoom;
    }

    public boolean isSupportAutoFocus() {
        return isSupportAutoFocus;
    }

}
